import pandas as pd
import tensorflow as tf
from matplotlib import pyplot as plt
from tensorflow.keras import layers

csv_file = tf.keras.utils.get_file('heart.csv', 'https://storage.googleapis.com/download.tensorflow.org/data/heart.csv')
df = pd.read_csv(csv_file)
df['thal'] = pd.Categorical(df['thal'])
df['thal'] = df.thal.cat.codes
target = df.pop('target')
dataset = tf.data.Dataset.from_tensor_slices((df.values, target.values))
for feet, tag in dataset.take(5):
    print('Features:{}, Target:{}'.format(feet, tag))

train_dataset = dataset.shuffle((len(df))).batch(32)

all_batche = tf.data.experimental.cardinality(train_dataset)
temp_dataset = train_dataset.take(all_batche // 5)
training_dataset = train_dataset.skip(all_batche // 5)

test_batches= tf.data.experimental.cardinality(temp_dataset)
test_dataset = temp_dataset.take(test_batches // 2)
validation_dataset = temp_dataset.skip(test_batches // 2)


model = tf.keras.Sequential([
    layers.Dense(64, activation='sigmoid'),
    layers.Dense(128, activation='sigmoid'),
    layers.Dense(256, activation='sigmoid'),
    layers.Dense(128, activation='sigmoid'),
    layers.Dense(64, activation='sigmoid'),
    layers.Dense(32, activation='sigmoid'),
    layers.Dense(1, activation='sigmoid')
])

model.compile(optimizer='adam',
              loss=tf.keras.losses.BinaryCrossentropy(),
              metrics=['accuracy'])

epochs = 500
history = model.fit(
    training_dataset,
    validation_data=validation_dataset,
    epochs=epochs
)

acc = model.evaluate(test_dataset)
print("Accuracy:", acc)

acc1 = history.history['accuracy']
val_acc = history.history['val_accuracy']

loss1 = history.history['loss']
val_loss = history.history['val_loss']

plt.figure(figsize=(8, 8))
plt.subplot(2, 1, 1)
plt.plot(acc1, label='Training Accuracy')
plt.plot(val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.ylabel('Accuracy')
plt.ylim([min(plt.ylim()), 1])
plt.title('Training and Validation Accuracy')

plt.subplot(2, 1, 2)
plt.plot(loss1, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.ylabel('Cross Entropy')
plt.ylim([0, 1.0])
plt.title('Training and Validation Loss')
plt.xlabel('epoch')
plt.show()
